/*
 * iic.c
 *
 *  Created on: 2014-3-9
 *      Author: Rome
 */


#include"string.h"
#include <stdio.h>
#include <unistd.h>

#include "time.h"
#include "iic.h"
#define DELAY_TIME 3
//#define Set_SDA  IOWR_ALTERA_AVALON_PIO_DATA(I2C_SDA_BASE, 0x1)
//#define Clr_SDA  IOWR_ALTERA_AVALON_PIO_DATA(I2C_SDA_BASE, 0x0)
//#define Set_SCL  IOWR_ALTERA_AVALON_PIO_DATA(I2C_SCL_BASE, 0x1)
//#define Clr_SCL  IOWR_ALTERA_AVALON_PIO_DATA(I2C_SCL_BASE, 0x0)

void I2C_SetOutput(unsigned int addr)
{
	IOWR_ALTERA_AVALON_PIO_DIRECTION(addr, 1);
}

void I2C_SetInput(unsigned int addr)
{
	IOWR_ALTERA_AVALON_PIO_DIRECTION(addr, 0);
}

void I2C_SetBit(unsigned int addr)
{
	IOWR_ALTERA_AVALON_PIO_DATA(addr, 0x1);
}

void I2C_ClearBit(unsigned int addr)
{
	IOWR_ALTERA_AVALON_PIO_DATA(addr, 0x0);
}

alt_u8 I2C_GetBit(unsigned int addr)
{
	return IORD_ALTERA_AVALON_PIO_DATA(addr);
}

void I2C_Start(I2C i2c)
{ /*
      SDA -------_________
      SCL ------------____
*/
  //????
	//Set_SDA;
	//Set_SCL;
	I2C_SetOutput(i2c.sda);
	I2C_SetOutput(i2c.scl);
	I2C_SetBit(i2c.sda);
	I2C_SetBit(i2c.scl);

	usleep(DELAY_TIME);

	//Clr_SDA;
	I2C_ClearBit(i2c.sda);
	usleep(DELAY_TIME);

	//Clr_SCL;
	I2C_ClearBit(i2c.scl);
	usleep(DELAY_TIME);
}

void I2C_Stop(I2C i2c)
{ /*
      SDA _________--------
      SCL ____-------------
*/
	//????
//	IOWR_ALTERA_AVALON_PIO_DIRECTION(I2C_SDA_BASE, 0x1);
//	IOWR_ALTERA_AVALON_PIO_DIRECTION(I2C_SCL_BASE, 0x1);
	I2C_SetOutput(i2c.sda);
	I2C_SetOutput(i2c.scl);
//	Clr_SDA;
//	Clr_SCL;
	I2C_ClearBit(i2c.sda);
	I2C_ClearBit(i2c.scl);
	usleep(DELAY_TIME);

//	Clr_SDA;
//	Set_SCL;
	I2C_SetBit(i2c.scl);
	usleep(DELAY_TIME);

//	Set_SDA;
	I2C_SetBit(i2c.sda);
	usleep(DELAY_TIME);
}

void I2C_Ack(I2C i2c)//?????
{
//	IOWR_ALTERA_AVALON_PIO_DIRECTION(I2C_SDA_BASE, 0x1);
//	IOWR_ALTERA_AVALON_PIO_DIRECTION(I2C_SCL_BASE, 0x1);
//	Clr_SDA;
	I2C_SetOutput(i2c.sda);
	I2C_SetOutput(i2c.scl);
	I2C_ClearBit(i2c.sda);
	usleep(DELAY_TIME);
//	Set_SCL;
	I2C_SetBit(i2c.scl);
	usleep(DELAY_TIME);
	//while(IORD_ALTERA_AVALON_PIO_DATA(I2C_SDA_BASE)){;};
//	Clr_SCL;
	I2C_ClearBit(i2c.scl);
	usleep(DELAY_TIME);
}
void Check_Ack(I2C i2c)
{
	char a=1;
	// SDA = "Z"
	// SCL = 0
//	IOWR_ALTERA_AVALON_PIO_DIRECTION(I2C_SDA_BASE, 0x0);
//	//IOWR_ALTERA_AVALON_PIO_DIRECTION(I2C_SCL_BASE, 0x1);
	I2C_SetInput(i2c.sda);
//	Clr_SCL;
	I2C_ClearBit(i2c.scl);
	usleep(DELAY_TIME);

//	Set_SCL;
	I2C_SetBit(i2c.scl);
	usleep(DELAY_TIME);
	while(a) {
//		a = IORD_ALTERA_AVALON_PIO_DATA(I2C_SDA_BASE);
		a = I2C_GetBit(i2c.sda);
		usleep(DELAY_TIME);
	// printf("waiting ACK a is %d\n",a);
	 }
	usleep(DELAY_TIME);//
	//printf("detected ACK\n");
//	Clr_SCL;
	I2C_ClearBit(i2c.scl);
	usleep(DELAY_TIME);
}

void I2C_Nack(I2C i2c)//?????
{
//	IOWR_ALTERA_AVALON_PIO_DIRECTION(I2C_SDA_BASE, 0x1);
//	IOWR_ALTERA_AVALON_PIO_DIRECTION(I2C_SCL_BASE, 0x1);
	I2C_SetOutput(i2c.sda);
	I2C_SetOutput(i2c.scl);
//	Set_SDA;
	I2C_SetBit(i2c.sda);
	usleep(DELAY_TIME);
//	Set_SCL;
	I2C_SetBit(i2c.scl);
	usleep(DELAY_TIME);
//	Clr_SCL;
	I2C_ClearBit(i2c.scl);
	usleep(DELAY_TIME);
}

void I2C_Send_Byte(I2C i2c, char d)
{
	unsigned char i = 8;
//	IOWR_ALTERA_AVALON_PIO_DIRECTION(I2C_SDA_BASE, 0x1);
//	IOWR_ALTERA_AVALON_PIO_DIRECTION(I2C_SCL_BASE, 0x1);
	I2C_SetOutput(i2c.sda);
	I2C_SetOutput(i2c.scl);
	usleep(DELAY_TIME);

/*
                    MSB
    SDA  ______-------------__________

    SCL  _________-------_____________

 */

//  Clr_SDA;
//  Clr_SCL;
	I2C_ClearBit(i2c.sda);
	I2C_ClearBit(i2c.scl);
	usleep(DELAY_TIME);

	while( i-- )	  {
	    if (d & 0x80)
//	        Set_SDA;
	    	I2C_SetBit(i2c.sda);
	    else
//	        Clr_SDA;
	    	I2C_ClearBit(i2c.sda);
	    usleep(DELAY_TIME);

//	    Set_SCL;
	    I2C_SetBit(i2c.scl);
	    usleep(DELAY_TIME);
//	    Clr_SCL;
	    I2C_ClearBit(i2c.scl);
	    usleep(DELAY_TIME);

//	    Clr_SDA;
//	    Clr_SCL;
	    I2C_ClearBit(i2c.sda);
	    usleep(DELAY_TIME);

	    d = d << 1;
   }
	usleep(DELAY_TIME);

}


unsigned char I2C_Receive_Byte(I2C i2c)
{
	unsigned char rn = 8, data = 0, rr = 0x80;
//	IOWR_ALTERA_AVALON_PIO_DIRECTION(I2C_SDA_BASE, 0x0);
//	IOWR_ALTERA_AVALON_PIO_DIRECTION(I2C_SCL_BASE, 0x1);
	I2C_SetInput(i2c.sda);
	I2C_SetOutput(i2c.scl);
	usleep(DELAY_TIME);
	for(;rn!=0;rn--)
	{
//		Set_SCL;
		I2C_SetBit(i2c.scl);
		usleep(DELAY_TIME);
//		if (IORD_ALTERA_AVALON_PIO_DATA(I2C_SDA_BASE)){
		if (I2C_GetBit(i2c.sda)){
			data|=rr;
			//printf("IORD_ALTERA_AVALON_PIO_DATA",IORD_ALTERA_AVALON_PIO_DATA(I2C_SDA_BASE));
		}else{
			data&=~rr;
		}
		rr>>=1;
//		Clr_SCL;
		I2C_ClearBit(i2c.scl);
		usleep(DELAY_TIME);
	}
	//printf("I2C_Receive_Byte is %x\n",data);
	return data;
}



